##
## Replication file for appendix analyses of Brad Epperly, Chris Witko, Ryan Strickler, and Paul White, "Rule by Violence, Rule by Law," in Perspectives on Politics
## See readme file and main article replication file for additional information
##

setwd("~/fillintheblank")

library(ggplot2) # Figures
library(extrafont) # Fonts
library(lme4) # Multilevel models
library(simcf) # For creating subsets of data, see Chris Adolph's webpage if it's not available on CRAN
library(memisc) # Tables
library(texreg) # Tables
options(scipen=120,digits=2) # Output format

# Below, change to wherever you have downloaded the data:
alldata2 <- read.csv("~/Desktop/epperly_etal_lynching_perspectives_data.csv")


# Table 1 is just summary statistics
summary(pre_anytwo$pr)
summary(post_anytwo$pr)
summary(pre_anytwo$ppop)
summary(post_anytwo$ppop)
summary(pre_anytwo$percentblack100)
summary(post_anytwo$percentblack100)
summary(pre_anytwo$cotratio)
summary(post_anytwo$cotratio)

# Table 2 is just Jim Crow laws by state

# Table 3: Including probable lynchings
# Modeling probable and confirmed lynchings
 
formP <- black_lynching ~  daystoelection1 + pr + ppop + 
	percentblack100 + cotratio + year + State + Black
pre_anytwo.prob <- subset(alldata2, fulladditivejimcrow <2)
post_anytwo.prob  <- subset(alldata2, fulladditivejimcrow>=2)
pre_anytwo.prob  <- extractdata(formP, pre_anytwo.prob ,na.rm=TRUE)
post_anytwo.prob  <- extractdata(formP, post_anytwo.prob ,na.rm=TRUE)

fe.twopre1.prob <- glm(black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) +  
	scale(percentblack100) + scale(I(percentblack100^2))  + 
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= pre_anytwo.prob)			
hlm.twopre1.prob <- glmer(black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2))  + 
	scale(cotratio) + scale(year) + (1|State),
	family=binomial(link="logit"),data= pre_anytwo.prob)			
fe.twopost1.prob <- glm(black_lynching ~  scale(daystoelection1) +
	scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2))  + 
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= post_anytwo.prob)			
hlm.twopost1.prob <- glmer(black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2))  + 
	scale(cotratio) + scale(year) + (1|State),
	family=binomial(link="logit"),data= post_anytwo.prob)			
# TABLE 3:	
screenreg(list(fe.twopre1.prob, hlm.twopre1.prob, fe.twopost1.prob, hlm.twopost1.prob),omit.coef="State",
	stars=c(0.001,0.01,0.05,0.1),symbol="\\dagger",
	digits=2,booktabs=TRUE,dcolumn=TRUE)
	
	
# Table 4: Alternative ways of operationalizing Jim Crow
# In the main manuscript we use the adoption of the 2nd voter suppression policy as the marker of the beginning of the Jim Crow disenfranchisement era. Here we do it differently.
# First, the "big two" policies of the poll tax and literacy test (big two in the sense that these are the two most common policies discussed in studies of Jim Crow and voter suppression). Second, the white primary, arguably the culmination of the Jim Crow era policies, and thus the most conservative with the start of Jim Crow

form1 <- confirmed_black_lynching ~  daystoelection1 + pr + ppop + 
	percentblack100  + cotratio + year + State + 
	num_confirmed_black_lynchings 
			
alldata2$bigtwo <- 0
alldata2$bigtwo[alldata2$polltax==1  & alldata2$literacytest==1] <-1
bigtwopre <- subset(alldata2,bigtwo==0)
bigtwopost <- subset(alldata2,bigtwo==1)
bigtwopre <- extractdata(form1, bigtwopre,na.rm=TRUE)
bigtwopost <- extractdata(form1, bigtwopost,na.rm=TRUE)
	
fe.bigtwopre1 <- glm(confirmed_black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2))  + 
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= bigtwopre)			
fe.bigtwopost1 <- glm(confirmed_black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2))  + 
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data=bigtwopost)	

preWP <- subset(alldata2,whiteprimary==0)
postWP <- subset(alldata2,whiteprimary==1)
preWP <- extractdata(form1, preWP,na.rm=TRUE)
postWP <- extractdata(form1, postWP,na.rm=TRUE)
	
fe.wp_pre <- glm(confirmed_black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2))  +  
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= preWP)
fe.wp_post <- glm(confirmed_black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2))  +  
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data=postWP)
# TABLE 4:	
screenreg(list(fe.bigtwopre1, fe.bigtwopost1, fe.wp_pre, fe.wp_post),
	stars=c(0.001,0.01,0.05,0.1),omit.coef="State",
	digits=2,booktabs=TRUE,dcolumn=TRUE)
		
# Table 5, like Table 4, looks at alternative operationalizations of Jim Crow, but uses probable and confirmed (rather than just confirmed) lynchings as the outcome.
bigtwopre.prob <- subset(alldata2,bigtwo==0)
bigtwopost.prob <- subset(alldata2,bigtwo==1)
bigtwopre.prob <- extractdata(formP, bigtwopre.prob ,na.rm=TRUE)
bigtwopost.prob <- extractdata(formP, bigtwopost.prob ,na.rm=TRUE)
fe.bigtwopre1.prob <- glm(black_lynching ~  scale(daystoelection1) +
	scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2))  + 
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= bigtwopre.prob)			
fe.bigtwopost1.prob <- glm(black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2))  + 
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data=bigtwopost.prob)	
preWP.prob <- subset(alldata2,whiteprimary==0)
postWP.prob <- subset(alldata2,whiteprimary==1)
preWP.prob <- extractdata(formP, preWP.prob,na.rm=TRUE)
postWP.prob <- extractdata(formP, postWP.prob,na.rm=TRUE)
fe.wp_pre.prob <- glm(black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2))  +  
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= preWP.prob)
fe.wp_post.prob <- glm(black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2))  +  
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data=postWP.prob)
# TABLE 5:	
screenreg(list(fe.bigtwopre1.prob, fe.bigtwopost1.prob, 
	fe.wp_pre.prob, fe.wp_post.prob),omit.coef="State",
	stars=c(0.001,0.01,0.05,0.1),
	digits=2,booktabs=TRUE,dcolumn=TRUE)	

# Yet another alternative way to code the beginning of full legalized disenfranchisement is with the success of constitutional "disenfranchisement conventions" proposed and held throughout Southern states. As Kousser details, the impetus for these was the final resolution of the question of black suffrage, and many Democrats felt without a constitutional resolution there was a chance at statutory resolutions being not fully succesful. Thus, in the analysis below we use an alternative means of coding the "break point."
# Table 6, like Tablse 4-5, looks at alternative operationalizations of Jim Crow, but uses the holding of a "disenfranchising convention" as the beginning of Jim Crow. Will do this for both confirmed and probable+confirmed lynchings.

# setting the dates
alldata2$convention <- 0
alldata2$convention[alldata2$State=="Alabama" & alldata2$year > 1901] <- 1
alldata2$convention[alldata2$State=="Mississippi" & alldata2$year > 1890] <- 1
alldata2$convention[alldata2$State=="Louisiana" & alldata2$year > 1898] <- 1
alldata2$convention[alldata2$State=="South Carolina" & alldata2$year > 1895] <- 1
alldata2$convention[alldata2$State=="Virginia" & alldata2$year > 1902] <- 1
# Virginia is unchanged
alldata2$convention[alldata2$State=="North Carolina" & alldata2$year > 1900] <- 1
# North Carolina had a constitutional amendment "to settle this question [black voting] once and for all" (Speaker of State House, 1899) approved in 1900
alldata2$convention[alldata2$State=="Georgia" & alldata2$year > 1908] <- 1
# Although GA pionered the poll tax, there were pushes to have a disenfranchising convention until successful in 1908
# TN, FL, and Arkansas were unsuccessful in having conventions for various reasons, so the dates remain unchanged
alldata2$convention[alldata2$State=="Tennessee" & alldata2$year > 1889] <- 1
alldata2$convention[alldata2$State=="Florida" & alldata2$year > 1889] <- 1
alldata2$convention[alldata2$State=="Arkansas" & alldata2$year > 1892] <- 1
form.convention <- confirmed_black_lynching ~  daystoelection1 + pr + ppop + 
	percentblack100 +  scotratio + year + State + 
	num_confirmed_black_lynchings + convention
pre_anytwoC <- subset(alldata2, convention==0)
post_anytwoC <- subset(alldata2, convention==1)
pre_anytwoC <- extractdata(form.convention, pre_anytwoC,na.rm=TRUE)
post_anytwoC <- extractdata(form.convention, post_anytwoC,na.rm=TRUE)
fe.twopreC <- glm(confirmed_black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) +  
	scale(percentblack100) + scale(I(percentblack100^2))  + 
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= pre_anytwoC)			
fe.twopostC <- glm(confirmed_black_lynching ~  scale(daystoelection1) + 
	scale(ppop) + scale(pr) +  
	scale(percentblack100) + scale(I(percentblack100^2))  + 
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= post_anytwoC)
formPC <- black_lynching ~  daystoelection1 + pr + ppop + percentblack100 +
	cotratio + year + State + convention
pre_anytwo.probC <- subset(alldata2, convention==0)
post_anytwo.probC  <- subset(alldata2, convention==1)
pre_anytwo.probC  <- extractdata(formPC, pre_anytwo.probC ,na.rm=TRUE)
post_anytwo.probC  <- extractdata(formPC, post_anytwo.probC ,na.rm=TRUE)
fe.twopre1.probC <- glm(black_lynching ~  scale(daystoelection1) + scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= pre_anytwo.probC)			
fe.twopost1.probC <- glm(black_lynching ~  scale(daystoelection1) + scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= post_anytwo.probC)			
# TABLE 6:
screenreg(list(fe.twopreC, fe.twopre1.probC, fe.twopostC, fe.twopost1.probC),
	omit.coef="State")

# Table 7 looks at possible alternative dates for ending the analysis. In the manuscript we use 1952. This is still well before the end of the Jim Crow era, and before the end of lynchings of African Americans in the South as a phenomenon. However, it is plausibly after the "era of lynchings," which some identify as being  approximately the half century after the end of Reconstruction. We therefore model the Jim Crow era analysis with different end points.

pre_anytwo <- subset(alldata2, fulladditivejimcrow <2)
post_anytwo <- subset(alldata2, fulladditivejimcrow>=2)
pre_anytwo <- extractdata(form1, pre_anytwo,na.rm=TRUE) # Just have the variables of interest, remove missing data
post_anytwo <- extractdata(form1, post_anytwo,na.rm=TRUE) # Just have the variables of interest, remove missing data

pre1 <- glm(confirmed_black_lynching ~ scale(daystoelection1) + scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"), data=pre_anytwo)
post1 <- glm(confirmed_black_lynching ~ scale(daystoelection1) + scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,            
	family=binomial(link="logit"), data=post_anytwo)
post1925 <- glm(confirmed_black_lynching ~ scale(daystoelection1) + scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"), 
	data=post_anytwo, subset=year <1925)
post1930 <- glm(confirmed_black_lynching ~ scale(daystoelection1) + scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),
	data=post_anytwo, subset=year <1930)
post1935 <- glm(confirmed_black_lynching ~ scale(daystoelection1) + scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,               
	family=binomial(link="logit"), 
	data=post_anytwo, subset=year <1935)
# TABLE 7:
screenreg(list(post1,post1925,post1930,post1935),omit.coef="State"))


# Tables 8 and 9 use count models rather than the logistic regressions. We do this because we can use the actual number of lynching events rather than the simpler dichotomous 0/1 of whether an event occurred.
library(pscl)
library(MASS)
NB.anytwo_pre <- zeroinfl(num_confirmed_black_lynchings ~ scale(daystoelection1) +
	scale(ppop) + scale(pr) + scale(percentblack100) + 
	scale(I(percentblack100^2))  + scale(cotratio) + scale(year) + 
	State | 1,data= pre_anytwo,dist="negbin")
NB.anytwo_post <- zeroinfl(num_confirmed_black_lynchings ~ scale(daystoelection1) +
	scale(ppop) + scale(pr) + scale(percentblack100) + 
	scale(I(percentblack100^2))  + scale(cotratio) + scale(year) + 
	State | 1,data= post_anytwo,dist="negbin")
# TABLE 8:
screenreg(list(NB.anytwo_pre, NB.anytwo_post))
# Can also do this including probable lynchings
NB.anytwo_pre.prob <- zeroinfl(Black ~ scale(daystoelection1) + scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State | 1,
	data= pre_anytwo.prob,dist="negbin")
NB.anytwo_post.prob <- zeroinfl(Black ~ scale(daystoelection1) +scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State | 1,
	data= post_anytwo.prob,dist="negbin")
# TABLE 9:
screenreg(list(NB.anytwo_pre.prob, NB.anytwo_post.prob),omit.coef="State"))


# County-month observations are important for our days to election covariate, but mean that we have far more 0s than 1s, and thus rare events logit is used to verify our results are robust. Table 10 presents these results.
library(Zelig)

fe.twopre1 <- glm(confirmed_black_lynching ~  scale(daystoelection1) + scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= pre_anytwo)			
fe.twopost1 <- glm(confirmed_black_lynching ~  scale(daystoelection1) +scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"),data= post_anytwo)			
fe.twopre1.rare <- zelig(confirmed_black_lynching ~  scale(daystoelection1) +
	scale(ppop) + scale(pr) + scale(percentblack100) + 
	scale(I(percentblack100^2)) + scale(cotratio) + scale(year) + State,
	model="relogit",data= post_anytwo)			
fe.twopost1.rare <- zelig(confirmed_black_lynching ~  scale(daystoelection1) +
	scale(ppop) + scale(pr) + scale(percentblack100) + 
	scale(I(percentblack100^2)) + scale(cotratio) + scale(year) + State,
	model="relogit",data= pre_anytwo)	
# TABLE 10: rare events
screenreg(list(fe.twopre1, fe.twopre1.rare, fe.twopost1,fe.twopost1.rare),omit.coef="State")


# TABLE 11 is just Table 2 from the main article, this time reporting the state fixed and random effects.
screenreg(list(fe.twopre1, hlm.twopre1,fe.twopost1, hlm.twopost1))


# TABLE 12 reports the use of a seasonal dummy, either included in the analysis or (because of overlapping measurement) as a replacement for the days to election covariate
data <- alldata2
data$season <- NA
data$season[data$month > 8 & data$month < 12] <- "fall"
data$season[data$month > 11] <- "winter"
data$season[data$month < 3] <- "winter"
data$season[data$month > 2 & data$month < 6] <- "spring"
data$season[data$month > 5 & data$month < 9] <- "summer"
summary(as.factor(data$season))
data$summer <- 0
data$summer[data$season=="summer"] <- 1
summary(as.factor(data$summer))
form1 <- confirmed_black_lynching ~ daystoelection1 + pr + ppop + percentblack100 +
    cotratio + year + State + season + month + summer
pre_anytwo <-  subset(data, fulladditivejimcrow < 2)
post_anytwo <- subset(data, fulladditivejimcrow > 1)
pre_anytwo <- extractdata(form1, pre_anytwo, na.rm=TRUE)
post_anytwo <- extractdata(form1, post_anytwo, na.rm=TRUE)
pre1 <- glm(confirmed_black_lynching ~ scale(daystoelection1) + scale(ppop) +
	scale(pr) +scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,
    family=binomial(link="logit"), data=pre_anytwo)
pre2 <- glm(confirmed_black_lynching ~ scale(daystoelection1) + scale(ppop) +
	scale(pr) +scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + season + State,
	family=binomial(link="logit"), data=pre_anytwo)
pre2a <- glm(confirmed_black_lynching ~ season + scale(ppop) + scale(pr) +
	scale(percentblack100) + scale(I(percentblack100^2)) + 
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"), data=pre_anytwo)
post1 <- glm(confirmed_black_lynching ~ scale(daystoelection1) + scale(ppop) +
	scale(pr) + scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"), data=post_anytwo)
post2 <- glm(confirmed_black_lynching ~ scale(daystoelection1) + season +
	scale(ppop) + scale(pr) + scale(percentblack100) + 
	scale(I(percentblack100^2)) + scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"), data=post_anytwo)
post2a <- glm(confirmed_black_lynching ~ season + scale(ppop) + scale(pr) + 
	scale(percentblack100) + scale(I(percentblack100^2)) +
	scale(cotratio) + scale(year) + State,
	family=binomial(link="logit"), data=post_anytwo)
screenreg(list(pre1,pre2,pre2a,post1,post2,post2a),omit.coef="State")


# Tables 13-16 report the control of state governments, data from Burnham 1984, Partisian Division of American State Governments, 1834-1985. ICPSR.
